/*****************************************
**  Nom : COLLOMB - SALINAS - CARRUELLE	- RASPAUD aussi :)**
**	Nom du fichier : main.c				**
**	Description : Programme principal 	**
**				  moteur d'inférence	**
**										**
**										**
**	Date : 16/09/2014				    **
**  Statut : In Work					**
*****************************************/

/*****************************************
**  Zone de declaration des includes    **
*****************************************/

#include "struct.h"

/*****************************************
**  Zone de declaration des prototypes  **
*****************************************/
int menu(void);

/*****************************************
**  Zone du programme principal         **
*****************************************/

 int main (void)
 {
 	 int action=0;                    // Choix venant du menu
	 int test=-1;                     // Variable de retour des erreurs
 	 GAME Game_Status;
 	 char c;
 	 int pid;
 	 memset(&Game_Status,0,sizeof(GAME));
	 do
	 {
		 action = menu();               // Affichage du menu

		 switch(action)                 // Choix depuis le menu
		 {
			 case 1 : /* Debut Init fifos */
			 			 test = -1;
			 			 if(Game_Status.Default == 0) // On met la config par defaut
			 			 {
			 			 	printf("Config par default\n");
			 			 	InitPartie_ConfigurerPartie('R');
			 			 }

			 			 //memset(&Game_Status,0,sizeof(GAME));
				 		 Game_Status.table=InitPartie_InitFIFO(0);
						 Game_Status.J1=InitPartie_InitFIFO(1);
						 Game_Status.J2=InitPartie_InitFIFO(2);
						 Game_Status.J3=InitPartie_InitFIFO(3);
						 Game_Status.J4=InitPartie_InitFIFO(4);
						 test=InitPartie_InitPartie(&Game_Status.table,&Game_Status.J1,&Game_Status.J2,&Game_Status.J3,&Game_Status.J4);

						  if(test==-1)
						  {
							printf("MAIN : Erreur dans la fonction init_partie !\n");
							return 0;
						  }
                      /* Fin Init fifos */

					  /* Debut Creation liste regles */
						  Game_Status.fp = CreerListeCh_OuvrirFic(Fic_Regles,"r");
	 	 			 	  if(Game_Status.fp!=NULL && Game_Status.Tete_Res == NULL )
		 				  {
			 		 	  	 CreerListeCh_LireBases('R', Game_Status.fp, &Game_Status.Tete_Faits, &Game_Status.Tete_Res);
			 			 	 CreerListeCh_FermerFichier(Game_Status.fp);
			 		 	  }
                      /* FinCreation liste regles */

                      /* Debut Creation liste faits */
					 	  Game_Status.fp=CreerListeCh_OuvrirFic(Fic_Faits,"r");
		 				  if(Game_Status.fp!=NULL && Game_Status.Tete_Faits == NULL)
						  {
						 	 CreerListeCh_LireBases('F', Game_Status.fp, &Game_Status.Tete_Faits, &Game_Status.Tete_Res);
							 CreerListeCh_FermerFichier(Game_Status.fp);
						  }
                      /* Fin Creation liste faits */

                      /* Verification de la configuration */
						  DrlmntPartie_CheckConf(Game_Status.Tete_Faits, Game_Status.Tete_Res);
					  /* Tirage au sort du 1er joueur */
						  Game_Status.id_player = DrlmntPartie_Random(NOMBRE_JOUEUR);

					  /********** DEBUT DU BOUCLAGE DU PROGRAMME****************/

						  while(Game_Status.winner == 0) // Tant qu'il n'y a aucun gagnant
						  {
						  	Game_Status.winner = DrlmntPartie_CheckWinner(&Game_Status.J1, &Game_Status.J2, &Game_Status.J3, &Game_Status.J4); // Verification si un joueur gagne

						  	if(Game_Status.winner>0)
              				{
              					printf("Le joueur <%d> a gagne !!! \n",Game_Status.winner);
							  	CreerListeCh_FreeListe('R', &Game_Status.Tete_Res, &Game_Status.Tete_Faits); // On libere la memoire des listes de Fait et de Regles
			 		 		 	CreerListeCh_FreeListe('F', &Game_Status.Tete_Res, &Game_Status.Tete_Faits);
							  	InitPartie_Free_Carte(&Game_Status.table, &Game_Status.J1, &Game_Status.J2, &Game_Status.J3, &Game_Status.J4);
							  	break;
              				}
						    else
              				{
						  		printf("C'est au tour du joueur <%d> de jouer ! \n",Game_Status.id_player);
              				}

						  	switch (Game_Status.id_player) // Selection du joueur
						  	{
						  		case 1 : //J1

						  	 		  if (Game_Status.J1.nb_carte == 0) // Verifie si le joueur possede des cartes
						  	 		  {
                           			  	printf("Le joueur <%d> n'a plus de cartes ! ! \n",Game_Status.id_player);
                           			  	Game_Status.players_Eliminated |= Player1;
                           			  	Game_Status.nb_pose = 0;
                           			  	if(Game_Status.flag_recup == 1)
                           			  	{
                           			  		if((Game_Status.players_Eliminated & Player1) == Player1)
                           			  		{
                           			  			Game_Status.id_player = DrlmntPartie_WhoPlay(1, 1);
                           			  		}
                           			  		else
                           			  		{
		                       			  		Game_Status.flag_recup = 0;
		                       			  		DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J1);
		                       			  		Game_Status.id_player = DrlmntPartie_WhoPlay(3, 1);
		                       			  		Game_Status.players_Eliminated |= Player1;
                           			  		}
                           			  	}
                           			  	else
                           			  		Game_Status.id_player = DrlmntPartie_WhoPlay(1, 1);
						   	   	  	  }
						   			  else
						   			  {

						   			    c=getchar();
						   			  	if(c == '\n' || c != 'q')
						   			  	{
							   			  	if(Game_Status.nb_pose == 0)
							   			  	{

				               				  	if(Game_Status.flag_recup == 1)
												{
													DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J1);
													Game_Status.id_player = DrlmntPartie_WhoPlay(3, 1);
                           			  				Game_Status.flag_recup = 0;
												}
												else
												{
								  	   				DrlmntPartie_EchgFIFOin(&Game_Status.J1, &Game_Status.table);
								  	   				Game_Status.id_player = DrlmntPartie_WhoPlay(1, 1); // Joueur suivant
												}
											}
				               				else
				               				{
							  	   			  DrlmntPartie_EchgFIFOin(&Game_Status.J1, &Game_Status.table);
				               				  Game_Status.nb_pose --;
				               				}
						   			  	}

						   			  	else if(c == 'q')
						   			  	{
						   			  	 	printf("FIN DE LA PARTIE PAR ACTION DE L'UTILISATEUR\n");
						   			  	 	CreerListeCh_FreeListe('R', &Game_Status.Tete_Res, &Game_Status.Tete_Faits); // On libere la memoire des listes de Fait et de Regles
			 		 		 				CreerListeCh_FreeListe('F', &Game_Status.Tete_Res, &Game_Status.Tete_Faits);
							  				InitPartie_Free_Carte(&Game_Status.table, &Game_Status.J1, &Game_Status.J2, &Game_Status.J3, &Game_Status.J4);
							  				pid = fork();
							  				if (pid == 0)
							  				{
							  					exit(0);
							  				}
							  				else
							  					execv("./main", NULL);
						   			  	}
						   			  }


						  	 	      break;

						  	 case 2 : //J2
						  	 		  if (Game_Status.J2.nb_carte == 0)
						  	 		  {
                           			  	printf("Le joueur <%d> n'a plus de cartes ! ! \n",Game_Status.id_player);
                           			  	Game_Status.nb_pose = 0;
                           			  	if(Game_Status.flag_recup == 1)
                           			  	{
                           			  		if((Game_Status.players_Eliminated & Player2) == Player2)
                           			  		{
                           			  			Game_Status.id_player = DrlmntPartie_WhoPlay(2, 1);
                           			  		}
                           			  		else
                           			  		{
		                       			  		Game_Status.flag_recup = 0;
		                       			  		DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J1);
		                       			  		Game_Status.id_player = DrlmntPartie_WhoPlay(4, 1);
		                       			  		Game_Status.players_Eliminated |= Player2;
                           			  		}
                           			  	}
                           			  	else
                           			  		Game_Status.id_player = DrlmntPartie_WhoPlay(2, 1);
						   			  }
						   			  else
						   			  {
						  	   			if(Game_Status.nb_pose == 0)
						   			  	{

		                   				  	if(Game_Status.flag_recup == 1)
											{
												DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J1);
												Game_Status.id_player = DrlmntPartie_WhoPlay(4, 1);
												Game_Status.flag_recup = 0;
											}
											else
											{
												sleep(2); // Attend un moment avant de faire joueur le joueur
							  	   				DrlmntPartie_EchgFIFOin(&Game_Status.J2, &Game_Status.table);
							  	   				Game_Status.id_player = DrlmntPartie_WhoPlay(2, 1); // Joueur suivant
											}
										}
		                   				else
		                   				{
		                   				  sleep(2); // Attend un moment avant de faire joueur le joueur
							  	   		  DrlmntPartie_EchgFIFOin(&Game_Status.J2, &Game_Status.table);
		                   				  Game_Status.nb_pose --;
		                   				}

						   			  }

						  	 	      break;

						  	 	      //////////// IDEM JOUEUR 3 ET 4 ///////////
						  	 case 3 : //J3
						  	 		  if (Game_Status.J3.nb_carte == 0)
						  	 		  {
                                      	printf("Le joueur <%d> n'a plus de cartes ! ! \n",Game_Status.id_player);
                                      	Game_Status.nb_pose = 0;
                           			  	if(Game_Status.flag_recup == 1)
                           			  	{
                           					if((Game_Status.players_Eliminated & Player3) == Player3)
                           			  		{
                           			  			Game_Status.id_player = DrlmntPartie_WhoPlay(3, 1);
                           			  		}
                           			  		else
                           			  		{
		                       			  		Game_Status.flag_recup = 0;
		                       			  		DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J1);
		                       			  		Game_Status.id_player = DrlmntPartie_WhoPlay(1, 1);
		                       			  		Game_Status.players_Eliminated |= Player3;
                           			  		}
                           				}
                           				else
                           			  		Game_Status.id_player = DrlmntPartie_WhoPlay(3, 1);
						   			  }
						   			  else
						   			  {
						  	   			if(Game_Status.nb_pose == 0)
						   			  	{
		                   				  	 // Joueur suivant
		                   				  	if(Game_Status.flag_recup == 1)
											{
												DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J1);
												Game_Status.id_player = DrlmntPartie_WhoPlay(1, 1);
												Game_Status.flag_recup = 0;
											}
											else
											{
												sleep(2); // Attend un moment avant de faire joueur le joueur
							  	   				DrlmntPartie_EchgFIFOin(&Game_Status.J3, &Game_Status.table);
							  	   				Game_Status.id_player = DrlmntPartie_WhoPlay(3, 1);
											}
										}
		                   				else
		                   				{
		                   				  sleep(2); // Attend un moment avant de faire joueur le joueur
						  	   			  DrlmntPartie_EchgFIFOin(&Game_Status.J3, &Game_Status.table);
		                   				  Game_Status.nb_pose --;
		                   				}
						   			  }
						  	 	      break;

						  	 case 4 : //J4
						  	 		  if (Game_Status.J4.nb_carte == 0)
						  	 		  {
                            		  	printf("Le joueur <%d> n'a plus de cartes ! ! \n",Game_Status.id_player);
                            		  	Game_Status.nb_pose = 0;
                           			  	if(Game_Status.flag_recup == 1)
                           			  	{
                           			  		if((Game_Status.players_Eliminated & Player4) == Player4)
                           			  		{
                           			  			Game_Status.id_player = DrlmntPartie_WhoPlay(4, 1);
                           			  		}
                           			  		else
                           			  		{
		                       			  		Game_Status.flag_recup = 0;
		                       			  		DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J1);
		                       			  		Game_Status.id_player = DrlmntPartie_WhoPlay(2, 1);
		                       			  		Game_Status.players_Eliminated |= Player4;
                           			  		}
                           			  	}
                           			  	else
                           			  		Game_Status.id_player = DrlmntPartie_WhoPlay(4, 1);
						   			  }
						   			  else
						   			  {
						  	   			if(Game_Status.nb_pose == 0)
						   			  	{
		                   				  	 // Joueur suivant
		                   				  	if(Game_Status.flag_recup == 1)
											{
												DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J1);
												Game_Status.id_player = DrlmntPartie_WhoPlay(2, 1);
												Game_Status.flag_recup = 0;
											}
											else
											{
												sleep(2); // Attend un moment avant de faire joueur le joueur
							  	   				DrlmntPartie_EchgFIFOin(&Game_Status.J4, &Game_Status.table);
							  	   				Game_Status.id_player = DrlmntPartie_WhoPlay(4, 1);
											}
										}
		                   				else
		                   				{
		                   				  sleep(2); // Attend un moment avant de faire joueur le joueur
						  	   			  DrlmntPartie_EchgFIFOin(&Game_Status.J4, &Game_Status.table);
		                   				  Game_Status.nb_pose --;
		                   				}

						   			  }
 				  	 	      		  break;

						  	 default : printf("Erreur du switch de l'id_player du main\n");
						  	 		   return 0;
						   }
							   DrlmntPartie_CLEANfaits(Game_Status.Tete_Faits);                    // Nettoie la liste de fait apres le separateur
							   DrlmntPartie_MAJfaits(&Game_Status.table, Game_Status.Tete_Faits);              // Met a jour les faits avec les 3 dernieres cartes pose
							   DrlmntPartie_Affiche3Cartes(&Game_Status.table);                    // Affiche les 3 dernieres cartes a l'utilisateur
							   Game_Status.mask = 0;
							   test = ChngAvt_ChainageAvant(Game_Status.Tete_Res, Game_Status.Tete_Faits,&Game_Status.mask);      // Lancement du chainage avec les nouveaux faits

							   if(test)
							   {
							   	//	printf("C'est au tour du joueur <%d> de jouer Game_Status.nb_pose = <%d> ! \n",Game_Status.id_player,Game_Status.nb_pose);

							   		if((Game_Status.mask & 0x80) ==0x80)
							   		{
							   			//printf("DETECTION D'UN AS DE SA MERE L'AS\n");
							   			Game_Status.last_player = Game_Status.id_player;
										if(Game_Status.flag_recup == 1)
							   				Game_Status.id_player = DrlmntPartie_WhoPlay(Game_Status.id_player, 1);
							   			Game_Status.nb_pose = 4;
							   			Game_Status.flag_recup = 1;
							   		}
							   		if((Game_Status.mask & 0x40) ==0x40)
							   		{
							   			//printf("DETECTION D'UN ROI DE SA MERE L'ROI\n");
							   			Game_Status.last_player = Game_Status.id_player;
										if(Game_Status.flag_recup == 1)
						   					Game_Status.id_player = DrlmntPartie_WhoPlay(Game_Status.id_player, 1);
							   			Game_Status.nb_pose = 3;
							   			Game_Status.flag_recup = 1;
							   		}
							   		if((Game_Status.mask & 0x20) ==0x20)
							   		{
							   			//printf("DETECTION D'UNE DAME DE SA MERE LA DAME\n");
							   			Game_Status.last_player = Game_Status.id_player;
										if(Game_Status.flag_recup == 1)
							   				Game_Status.id_player = DrlmntPartie_WhoPlay(Game_Status.id_player, 1);
							   			Game_Status.nb_pose = 2;
							   			Game_Status.flag_recup = 1;
							   		}
							   		if((Game_Status.mask & 0x10) ==0x10)
							   		{
							   			//printf("DETECTION D'UN VALET DE SA MERE L'VALET\n");
							   			Game_Status.last_player = Game_Status.id_player;
										if(Game_Status.flag_recup == 1)
							   				Game_Status.id_player = DrlmntPartie_WhoPlay(Game_Status.id_player, 1);
							   	 		Game_Status.nb_pose = 1;
							   			Game_Status.flag_recup = 1;
							   		}

							   		if((Game_Status.mask & 0x01) == 0x01)
							   		{
							   			printf("C'est au tour du joueur <%d> de jouer \n",Game_Status.id_player);
							   			//printf("DETECTION D'UN TAPAGE\n");
							   			Game_Status.nb_pose = 0;
							   			Game_Status.flag_recup = 0;
							   			Game_Status.who_tape = DrlmntPartie_Tape_Joueur_Ordi(Game_Status.Tete_Faits, &Game_Status); // Recupere le numero du joueur qui a tape en 1er
								   		switch(Game_Status.who_tape)
								   		{
									   		case 1:
									   			DrlmntPartie_ViderTable(&Game_Status.table,&Game_Status.J1);           // Vide les carte de la table vers le joueur qui a gagne
									   			Game_Status.id_player = DrlmntPartie_WhoPlay(1, 0);        // Le joueur ayant tape rejoue
									   			break;
									   		case 2:
									   			DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J2);
									   			Game_Status.id_player = DrlmntPartie_WhoPlay(2, 0);
									   			break;
									   		case 3:
									   			DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J3);
									   			Game_Status.id_player = DrlmntPartie_WhoPlay(3, 0);
									   			break;
									   		case 4:
									   			DrlmntPartie_ViderTable(&Game_Status.table, &Game_Status.J4);
									   			Game_Status.id_player = DrlmntPartie_WhoPlay(4, 0);
									   			break;
								  		}
								  		DrlmntPartie_CLEANfaits(Game_Status.Tete_Faits);
							  			DrlmntPartie_MAJfaits(&Game_Status.table, Game_Status.Tete_Faits);
								  	}
							  }
						  }

					  break;

			 case 2 : AfficheRegles();
			 		  break;

			 case 3 : InitPartie_ConfigurerPartie('C');
			 		  Game_Status.Default = 1;
			 		  break;

			 case 4 : ChainArr_Simulation();
			 		  break;

			 case 5 :
			 		  CreerListeCh_FreeListe('R', &Game_Status.Tete_Res, &Game_Status.Tete_Faits);;
	 		          CreerListeCh_FreeListe('F', &Game_Status.Tete_Res, &Game_Status.Tete_Faits);
					  InitPartie_Free_Carte(&Game_Status.table, &Game_Status.J1, &Game_Status.J2, &Game_Status.J3, &Game_Status.J4);
					  InitPartie_ConfigurerPartie('R');
	 				  return 0;

	 		 default : printf("Choix incorrect ..!\n");
	 		 		break;

		 }
	 }while (1);
 }

 int menu(void)
 {
	int choix = 0;
	printf("\n\t1. Nouvelle partie");
	printf("\n\t2. Afficher les regles du jeu");
	printf("\n\t3. Config");
	printf("\n\t4. Tester chainage arrière");
	printf("\n\t5. Quitter \n");
	scanf("%d", &choix);
	getchar();
	return choix;
 }
